local BaseSprite = import('..views.BaseSprite')
local LoadingBar = import('..views.LoadingBar')

local EventDispatchCentre = import('..controllers.EventDispatchCentre')

local scheduler = require(cc.PACKAGE_NAME .. ".scheduler")
require("app.data.baseMap")
require("app.controllers.Matrix")

local MainScene = class("MainScene", function()
    return display.newScene("MainScene")
end)

gEventDispatchCentre = EventDispatchCentre.new()
gTouchEnable = true
gTouchUnEnable_Effect_Backet = false
gLandNumber = 0
gEnableLand = 0
gSprites = {}
gWallSprites = {}
gHintTimer = 0
gBuildingMatrix = false
gCheckGSpritesCount = 0
--gHintGroups = {}
function MainScene:ctor()


	math.newrandomseed()
	local touchLayer = display.newLayer():addTo(self)
	touchLayer:setTouchEnabled(true)
	touchLayer:addNodeEventListener(cc.NODE_TOUCH_EVENT, handler(self,self.onTouch))

	local background = display.newSprite('#background.png', display.cx, display.cy):addTo(self)
	background:setOpacity(64)
	background:setScale(1.1)
	local scoreText = display.newSprite('#score.png', 100, display.cy):addTo(self)
	scoreText:setScale(0.5)

	self.loadpar = LoadingBar.new():addTo(self)
	self.loadpar:pos(100,64)
	self.loadpar:setParent(0)
	self.scoreLable = cc.ui.UILabel.new({
            UILabelType = 2, text = "0", size = 48,color=cc.c3b(128,255,0,255)})
        :align(display.CENTER, 98, display.cy-70)
        :addTo(self)
    self.score = 0
    self.total = 100000

    local tmp = display.newSprite('#' .. SPRITE_SOURCES[1], 64, display.cy+64+48*4):addTo(self)
    tmp:setScale(0.25)
    tmp = display.newSprite('#' .. SPRITE_SOURCES[2], 64, display.cy+64+48*3):addTo(self)
    tmp:setScale(0.25)
    tmp = display.newSprite('#' .. SPRITE_SOURCES[3], 64, display.cy+64+48*2):addTo(self)
    tmp:setScale(0.25)
    tmp = display.newSprite('#' .. SPRITE_SOURCES[4], 64, display.cy+64+48):addTo(self)
    tmp:setScale(0.25)
    tmp = display.newSprite('#' .. SPRITE_SOURCES[5], 64, display.cy+64):addTo(self)
    tmp:setScale(0.25)

    ---[[ 
    self.sytle1NumberLable = cc.ui.UILabel.new({
            UILabelType = 2, text = "0", size = 24,color=cc.c3b(200,200,100,255)})
        :align(display.CENTER, 128, display.cy+64+48*4-5)
        :addTo(self)
    self.sytle2NumberLable = cc.ui.UILabel.new({
        UILabelType = 2, text = "0", size = 24,color=cc.c3b(200,200,100,255)})
    :align(display.CENTER, 128, display.cy+64+48*3-5)
    :addTo(self)
    self.sytle3NumberLable = cc.ui.UILabel.new({
        UILabelType = 2, text = "0", size = 24,color=cc.c3b(200,200,100,255)})
    :align(display.CENTER, 128, display.cy+64+48*2-5)
    :addTo(self)
    self.sytle4NumberLable = cc.ui.UILabel.new({
        UILabelType = 2, text = "0", size = 24,color=cc.c3b(200,200,100,255)})
    :align(display.CENTER, 128, display.cy+64+48-5)
    :addTo(self)
    self.sytle5NumberLable = cc.ui.UILabel.new({
        UILabelType = 2, text = "0", size = 24,color=cc.c3b(200,200,100,255)})
    :align(display.CENTER, 128, display.cy+64-5)
    :addTo(self)
    self.sytle1Number = 0
    self.sytle2Number = 0
    self.sytle3Number = 0
    self.sytle4Number = 0
    self.sytle5Number = 0

    self:createButtons()
    --]]

    --self.score:setString('100')

	--self.sprites = {}

	--[[ --娴嬭瘯鐭╅樀鐢熸垚
	MatrixMap.create(self) 													--鍒涘缓鐭╅樀
	printf('checkGSprites:%s',tostring(MatrixMap.checkGSprites(self)))
	if not MatrixMap.checkGSprites(self) then 								--濡傛灉鐭╅樀闇�瑕佷慨澶嶏紝鍒欎慨澶�
		MatrixMap.doReviseGSprites(self)
	end
	--MatrixMap.reviseRandomGSprites(self)
	if MatrixMap.checkGSpritesCanByDestory(self) then
		print('... the matrix is ok ...')
	else
		print('... the matrix is bad ...')
	end
	]]

	--[[  --娴嬭瘯checkGSpritesCanByDestory鍑芥暟锛屼笉鍙秷闄ょ煩闃甸噸缃�
	local num = 1
	for row=1,9 do
		num = 1
		for col=1,8 do
			--local file = SPRITE_SOURCES[col%2+1 + row%2]
			local file = SPRITE_SOURCES[num+row%2]
			num = num + 2
			if num >= 4 then num = 1 end
			local tmpSprite = BaseSprite.new({filename=file,row=row,column=col}):addTo(self)
			tmpSprite:setScale(0.5)
			gSprites[row] = gSprites[row] or {}
			gSprites[row][col] = tmpSprite
			tmpSprite:retain()
			if row == 5 and col == 4 then
				tmpSprite:setEffect('basket')
			end
		end
	end
	if MatrixMap.checkGSpritesCanByDestory(self) then
		print('... the matrix is ok ...')
	else
		print('... the matrix is bad ...')
		MatrixMap.reRandomGSprites(self)
	end
	]]



	--鍒涘缓鐭╅樀
	MatrixMap.create(self) 			
	--鍒ゆ柇鐢熸垚鐨勯殢鏈虹煩闃垫槸鍚︽甯革紝濡傛灉鏈夊彲娑堥櫎鐨勶紝鍒欐浛鎹㈠彲娑堥櫎鐨�										

	function checkMatrix()
		if not MatrixMap.checkGSprites(self) then 
			print('random create matrix is bad')	
			MatrixMap.doReviseGSprites(self)
		end
		--鍒ゆ柇鐭╅樀鏄惁鏈夊彲娑堥櫎鐨勶紝濡傛灉娌℃湁鍒欓噸鏂扮敓鎴�
		if MatrixMap.checkGSpritesCanByDestory(self) then
			print('... the matrix is ok ...')
			return true
		else
			print('... the matrix is bad ...')
			MatrixMap.reRandomGSprites(self) 								--閲嶆柊鐢熸垚鐭╅樀鍚庯紝缁х画鍒ゆ柇
			checkMatrix() 
			--[[	
			if not MatrixMap.checkGSprites(self) then 	
				print('random create matrix is bad')
				MatrixMap.doReviseGSprites(self)
			end		
			]]		
		end
	end
	checkMatrix()
	--audio.playMusic('background.mp3')
end

function MainScene:onEnter()
	print('... MainScene:onEnter ... ')
	self.scheduler = scheduler.scheduleGlobal(handler(self,self.onEnterFrame),0.1)
	audio.playMusic('background.mp3')
	gStopSoundEffect = true
	--local number = audio.getMusicVolume()
	--audio.setMusicVolume(number*0.6)
end

function MainScene:onExit()
	print('... MainScene:onExit ... ')
	--assert(false)
	audio.stopMusic()
	scheduler.unscheduleGlobal(self.scheduler)
	for row=1,9 do
		for col=1,8 do
			if baseMap[row][col] == 1 and baseWall[row][col] == 0 then
				if gSprites[row][col] then
					gSprites[row][col]:release()
				end
			end
		end
	end
	--gSprites = nil
end

local checkTurnMapNumber = 0
function MainScene:onEnterFrame()
	--print('... MainScene:onEnterFrame ... ')
	gHintTimer = gHintTimer + 1
	--printf('... onEnterFrame  gHintTimer=%d ...',gHintTimer)
	if gHintTimer > 150 then
		--printf('... hint ...')
		gHintTimer = 0
		local canDestory,hintGroups = MatrixMap.checkGSpritesCanByDestory() 
		---[[
		if canDestory then
			if gStopSoundEffect then audio.playSound('hint.mp3') end
			local index = math.random(1,#hintGroups)
			local groups = hintGroups[index]
			for _,p in ipairs(groups) do
				local col,row = p[1],p[2]
				gSprites[row][col]:runAction(cc.Sequence:create(
					cc.ScaleTo:create(0.2,0.6),
					cc.ScaleTo:create(0.4,0.4),
					cc.ScaleTo:create(0.4,0.6),
					cc.ScaleTo:create(0.4,0.4),
					cc.ScaleTo:create(0.3,0.5)
					)
				)
			end
		--else
		--	self:reBuildMatrix()
		end
		--]]
	end
	--[[
	gCheckGSpritesCount = gCheckGSpritesCount + 1
	if gCheckGSpritesCount > 5 then
		gCheckGSpritesCount = 0
		local canDestory = MatrixMap.checkGSpritesCanByDestory() 		--娴嬭瘯鐭╅樀鏄惁鏈夊彲娑堥櫎瀵硅薄
		if not canDestory then
			print('... not have items can by destory ...')
			--gBuildingMatrix = true
			self:reBuildMatrix()
		end
	end
	]]
	--[[

	]]
	--[[
	checkTurnMapNumber = checkTurnMapNumber + 1
	if checkTurnMapNumber >= 5 then
		--print('... checkTurnMapNumber ...')
		checkTurnMapNumber = 0
		checkBaseCanTurnMap()
	end
	]]
	MainScene.testLand()
end


intentToPoint = {
	{0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0}
}


isSelected = false
local isOrigin = true
local endMoved = false
local selectedSprite
local startPoint = {}
local currentPoint = {}
function MainScene:onTouch(event)
	
	if event.x < 320 then 
		printf('gLandNumber = %d' , gLandNumber)
		print('intentToPoint:')
		for r=1,9 do
			printf('{%d,%d,%d,%d,%d,%d,%d,%d}',intentToPoint[r][1],intentToPoint[r][2],intentToPoint[r][3],intentToPoint[r][4],intentToPoint[r][5],intentToPoint[r][6],intentToPoint[r][7],intentToPoint[r][8])
		end
		print('baseCanTurnMap:')
		for r=1,9 do
			printf('{{%d,%d},{%d,%d},{%d,%d},{%d,%d},{%d,%d},{%d,%d},{%d,%d},{%d,%d}}',
			baseCanTurnMap[r][1][1],baseCanTurnMap[r][1][2],
			baseCanTurnMap[r][2][1],baseCanTurnMap[r][2][2],
			baseCanTurnMap[r][3][1],baseCanTurnMap[r][3][2],
			baseCanTurnMap[r][4][1],baseCanTurnMap[r][4][2],
			baseCanTurnMap[r][5][1],baseCanTurnMap[r][5][2],
			baseCanTurnMap[r][6][1],baseCanTurnMap[r][6][2],
			baseCanTurnMap[r][7][1],baseCanTurnMap[r][7][2],
			baseCanTurnMap[r][8][1],baseCanTurnMap[r][8][2]
			)
		end
	end
	gHintTimer = 0
	if gBuildingMatrix then return end
	local col,row = BaseSprite.toMatrix(event.x,event.y)
	event.col = col
	event.row = row
	if event.name == 'began' then
		if not gTouchEnable then print('... gTouchEnable is false ...') return false end
		if isDoingBasketEffect then print('isDoingBasketEffect is lock ') return false end
		if gEnableLand ~= 0 then printf('gEnableLand is lock :%d',gEnableLand) return false end
		if col then 								--鏈夋晥瑙︽懜
			return self:onTouchBegan(event)
		else
			if isSelected then
				selectedSprite:cancleSelectedEffect()
				isSelected = false
				selectedSprite = nil
			end
			return false
		end
	elseif event.name == 'moved' then
		return self:onTouchMoved(event)
	else
		return self:onTouchEnded(event)
	end

end



function MainScene:onTouchBegan(event)
	startPoint = {row=event.row,col=event.col}
	isOrigin = true 								--鍒锋柊褰撳墠鐐规爣璁�
	if not isOKPoint(startPoint) then 				--鏃犳晥鐨勮Е鎽哥偣锛屽鏋滀箣鍓嶆湁閫変腑涓滆タ锛岀洿鍙栨秷閫変腑
		if isSelected then
			selectedSprite:cancleSelectedEffect()
			isSelected = false
			selectedSprite = nil
		end
		return false
	else
		if isSelected then
			local dx = startPoint.col - selectedSprite.col
			local dy = startPoint.row - selectedSprite.row
			local result = false
			if dx == 1 and dy == 0 then
				--print('... right ...')
				gEventDispatchCentre:dispatchEvent({name = 'onTouchRight',point={col=selectedSprite.col,row=selectedSprite.row}})
			elseif dx == -1 and dy == 0 then
				--print('... left ...')
				gEventDispatchCentre:dispatchEvent({name = 'onTouchLeft',point={col=selectedSprite.col,row=selectedSprite.row}})
			elseif dx == 0 and dy == 1 then
				--print('... up ...')
				gEventDispatchCentre:dispatchEvent({name = 'onTouchUp',point={col=selectedSprite.col,row=selectedSprite.row}})
			elseif dx == 0 and dy == -1 then
				--print('... down ...')
				gEventDispatchCentre:dispatchEvent({name = 'onTouchDown',point={col=selectedSprite.col,row=selectedSprite.row}})
			else
				result = true	
			end
			if not result then
				--print('MainScene:onTouchBegan cancleSelectedEffect')
				selectedSprite:cancleSelectedEffect()
				isSelected = false
				selectedSprite = nil
				return false
			else 
				return true
			end
		else return true
		end
	end
end
function MainScene:onTouchMoved(event)
	if endMoved then return end 					--濡傛灉缁撴潫浜嗙Щ鍔ㄤ簨浠讹紝鐩撮��鍑�
	local row,col = event.row,event.col
	if row ~= startPoint.row or col ~= startPoint.col then
		endMoved = true 							--瑙︽懜绉诲姩锛岀Щ鍑哄綋鍓嶆牸鍒欒Е鎽哥Щ鍔ㄧ畻缁撴潫
		isOrigin = false
		if isSelected then 
			selectedSprite:cancleSelectedEffect()
			isSelected = false
			selectedSprite = nil
		end
		if not isOKPoint({row=row,col=col}) then    --濡傛灉鏄棤鏁堢偣锛屽垯鐩存帴閫�鍑�
			--if isSelected then 						--濡傛灉鏈夐�変腑鏁堟灉锛屽垯鍙栨秷
			--	BaseSprite.cancleSelectedEffect(selectedPoint.col,selectedPoint.row)
			--	isSelected = false
			--	selectedPoint = nil
			--end
			return
		else
			local dx = col - startPoint.col
			local dy = row - startPoint.row
			if dx == 1 and dy == 0 then
				--print('... right ...')
				gEventDispatchCentre:dispatchEvent({name = 'onTouchRight',point={col=startPoint.col,row=startPoint.row}})
			elseif dx == -1 and dy == 0 then
				--print('... left ...')
				gEventDispatchCentre:dispatchEvent({name = 'onTouchLeft',point={col=startPoint.col,row=startPoint.row}})
			elseif dx == 0 and dy == 1 then
				--print('... up ...')
				gEventDispatchCentre:dispatchEvent({name = 'onTouchUp',point={col=startPoint.col,row=startPoint.row}})
			elseif dx == 0 and dy == -1 then
				--print('... down ...')
				gEventDispatchCentre:dispatchEvent({name = 'onTouchDown',point={col=startPoint.col,row=startPoint.row}})
			end

		end

	end
end
function MainScene:onTouchEnded(event)
	if isOrigin then
	--濡傛灉涔嬪墠鏈夐�変腑涓斾负涓嶅悓鐐癸紝鍒欐洿鎹㈤�変腑锛屽惁鍒欑洿鎺ラ�変腑褰撳墠鐐�
		if isSelected then
			if selectedSprite.col == event.col and selectedSprite.row == event.row then
				selectedSprite:cancleSelectedEffect()
				selectedSprite = nil
				isSelected = false
			else
				selectedSprite:cancleSelectedEffect()
				gSprites[event.row][event.col]:setSelectedEffect(event.col,event.row)
				selectedSprite = gSprites[event.row][event.col]
			end
		else
			gSprites[event.row][event.col]:setSelectedEffect(event.col,event.row)
			selectedSprite = gSprites[event.row][event.col]
			isSelected = true
		end
	else
	end
	endMoved = false
end

function isOKPoint(point)
	local row = point.row
	local col = point.col
	if not row or not col then return false end
	local sprite = gSprites[row][col]
	if not sprite then print('... isOKPoint not have sprite ...') return false end

	if sprite.sytle == 11 or sprite.sytle == 0 then return false
	else return true
	end
end

gLandNumber = 0

function MainScene:testLand()
	if gBuildingMatrix then return end
	if gLandNumber > 0 then return end
	gLandNumber = 0
	if isDoingBasketEffect then return end

	MainScene.onLandOver()

	if MainScene.onLandTurn() then return end

	--[[
	local canDestory,gHintGroups = MatrixMap.checkGSpritesCanByDestory() 		--娴嬭瘯鐭╅樀鏄惁鏈夊彲娑堥櫎瀵硅薄
	if not canDestory then
		print('... not have items can by destory ...')
		--gBuildingMatrix = true
		self:reBuildMatrix()
	end
	]]
	--[[
	if canDestory then
		for k,v in ipairs(points) do
			for _k,_v in ipairs(v) do
				printf('the group %d : (%d,%d)',_k,_v[1],_v[2])
			end
		end
	end
	]]

	local isSearched = {}
	local gLandSprites = {} 						--鐜版湁绮剧伒寰�涓嬮檷
	local gAddSprites = {} 							--鐢熸垚鏂扮殑绮剧伒寰�涓嬭惤
	for i=1,9 do
		for j=1,8 do
			isSearched[i] = isSearched[i] or {}
			isSearched[i][j] = 0
		end
	end
	function searchRow(_col,_row)
		local col,row = _col,_row
		local number = 1
		local canLeft ,canRight = false,false


		local addArgs = {}
		addArgs.col = col

		addArgs.number = number
		for i=row+1,9 do
			if baseMap[i][col] == 0 or baseWall[i][col] == 1 then addArgs.number = 0 break end
			gSprites[i] = gSprites[i] or {}
			if not gSprites[i][col] then
				number = number + 1
				addArgs.number = number
			else
				local args = {}
				args.index = number
				args.sprite = gSprites[i][col]

				gLandSprites[#gLandSprites+1]=args
			end

			isSearched[i][col] = 1 						--鏍囪褰撳墠鏍煎凡缁忛亶鍘嗚繃锛屼笉闇�瑕佸啀閬嶅巻
		end

		if addArgs.number > 0 then
			gAddSprites[#gAddSprites+1] = addArgs
		end

	end

	for row=1,9 do
		for col=1,8 do
			if baseMap[row][col] == 1 and baseWall[row][col] == 0 then
				gSprites[row] = gSprites[row] or {}
				if not gSprites[row][col] and baseMap[row][col] == 1 and baseWall[row][col] == 0 and isSearched[row][col] == 0 then
					searchRow(col,row)
				end
			end
		end
	end


	for _,v in ipairs(gLandSprites) do
		if v.sprite then
			gLandNumber = gLandNumber + 1
			v.sprite.gLandNumber = v.sprite.gLandNumber + 1
			local dy = v.index*64

			v.sprite:runAction(cc.Sequence:create(
				cc.EaseSineIn:create(cc.MoveBy:create(0.1*(v.index+1),cc.p(0,-dy))), 
				--cc.EaseExponentialIn:create(cc.MoveBy:create(0.08*(v.index+1),cc.p(0,-dy))), 
				cc.CallFunc:create(function()
					--tmpSprite.conRemove = true
					--v.sprite.landPositions = nil
					gLandNumber = gLandNumber - 1
					v.sprite.gLandNumber = v.sprite.gLandNumber - 1
					gSprites[v.sprite.row][v.sprite.col] = nill
					v.sprite.row = v.sprite.row - v.index
					v.sprite.oldRow = v.sprite.row
					gSprites[v.sprite.row] = gSprites[v.sprite.row] or {}
					gSprites[v.sprite.row][v.sprite.col] = v.sprite
					--gEventDispatchCentre:dispatchEvent({name = 'onLandOver',tager=v.sprite,point={col=v.sprite.col,row=v.sprite.row}})
					--gLandPositions[v.sprite.row][v.sprite.col] = 0
					if gStopSoundEffect then audio.playSound('load.mp3') end
				end)
				)
			)
			--gLandPositions[v.sprite.row-v.index][v.sprite.col] = 1
		end

	end

	for _,v in ipairs(gAddSprites) do
		local col = v.col

		
		for i=1,v.number do
			gLandNumber = gLandNumber + 1
			local file = SPRITE_SOURCES[math.random(1,5)]
			local tmpSprite = BaseSprite.new({filename=file,row=9+i,column=col}):addTo(display.getRunningScene())
			local dy = v.number*64
			tmpSprite:setScale(0.5)
			tmpSprite:retain()
			--gLandPositions[9+i-v.number][v.col] = 1
			tmpSprite.gLandNumber = tmpSprite.gLandNumber + 1
			tmpSprite:runAction(cc.Sequence:create(
					cc.EaseSineIn:create(cc.MoveBy:create(0.1*(v.number+1),cc.p(0,-dy))),  
					--cc.EaseExponentialIn:create(cc.MoveBy:create(0.08*(v.number+1),cc.p(0,-dy))),  
					cc.CallFunc:create(function()
						tmpSprite.conRemove = true
						gLandNumber = gLandNumber - 1
						tmpSprite.gLandNumber = tmpSprite.gLandNumber - 1
						tmpSprite.row = tmpSprite.row - v.number
						tmpSprite.oldRow = tmpSprite.row
						gSprites[tmpSprite.row] = gSprites[tmpSprite.row] or {}
						gSprites[tmpSprite.row][tmpSprite.col] = tmpSprite
						--gEventDispatchCentre:dispatchEvent({name = 'onLandOver',tager=tmpSprite,point={col=tmpSprite.col,row=tmpSprite.row}})
						--gLandPositions[tmpSprite.row][tmpSprite.col] = 0
						if gStopSoundEffect then audio.playSound('load.mp3') end
					end)
				)
			)
		end
	end
end

function MainScene.onLandOver()

	for r=1,9 do
		for c=1,8 do
			if baseMap[r][c] == 1 and baseWall[r][c] == 0 then
				gSprites[r] = gSprites[r] or {}
				local sprite = gSprites[r][c]
				if sprite then
					local h1,v1,hp1,vp1 = BaseSprite.judgeItem(sprite)
					if h1 and v1 then
						--printf('... doing on onLandOver (%d,%d) h1=%d,v1=%d,hp1=%d,vp1=%d ...',sprite.col,sprite.row,h1,v1,hp1.began,vp1.began)
					end
					local destoryArgs = {}
					if h1>2 or v1>2 then
						--1
						if h1>2 and v1>2 then 									--T娑�
							for i=hp1.began,hp1.ended do
								if i ~= sprite.col then
									destoryArgs = {}
									destoryArgs.sprite = gSprites[sprite.row][i]  
									destoryArgs.score = 240
									destoryArgs.notDisplayscore = false
									destoryArgs.changeToEffect = false
									gDestoryPool[#gDestoryPool+1] = destoryArgs 				--寰�娓呴櫎姹犻噷鍔犲叆瀵硅薄
								end
							end
							for i=vp1.began,vp1.ended do
								if i ~= sprite.row then
									destoryArgs = {}
									destoryArgs.sprite = gSprites[i][sprite.col]  
									destoryArgs.score = 240
									destoryArgs.notDisplayscore = false
									destoryArgs.changeToEffect = false
									gDestoryPool[#gDestoryPool+1] = destoryArgs 				--寰�娓呴櫎姹犻噷鍔犲叆瀵硅薄
								end
							end
							destoryArgs = {}
							destoryArgs.sprite = sprite 
							destoryArgs.score = 240
							destoryArgs.notDisplayscore = false
							destoryArgs.changeToEffect = 'basket'
							gDestoryPool[#gDestoryPool+1] = destoryArgs 				--寰�娓呴櫎姹犻噷鍔犲叆瀵硅薄
						elseif h1>2 then  
							--print('... in horizontal ...')                                         
							for i=hp1.began,hp1.ended do
								--printf('add gDestoryPool row=%d,col=%d',sprite.row,i)
								if i ~= sprite.col then
									destoryArgs = {}
									destoryArgs.sprite = gSprites[sprite.row][i]  
									destoryArgs.score = 60*(h1-2)
									destoryArgs.notDisplayscore = false
									destoryArgs.changeToEffect = false
									gDestoryPool[#gDestoryPool+1] = destoryArgs 				--寰�娓呴櫎姹犻噷鍔犲叆瀵硅薄
								end
							end
							destoryArgs = {}
							destoryArgs.sprite = sprite  
							destoryArgs.score = 60*(h1-2)
							destoryArgs.notDisplayscore = false
							local toEffect = nil
							if h1>4 then toEffect = 'bomb' 							   --5娑�
							elseif h1 == 4 then toEffect = 'vertical' 				   --4娑�
							end
							if sprite.effect and sprite.effect ~= toEffect then 									   --濡傛灉涔嬪墠瀛樺湪鐗规晥锛屽垯澧炲姞涓�鐗规晥锛屽垹闄ゆ椂灏嗗悓鏃惰Е鍙�
								sprite.effect2 = toEffect
							else
								destoryArgs.changeToEffect = toEffect
							end
							gDestoryPool[#gDestoryPool+1] = destoryArgs 				--寰�娓呴櫎姹犻噷鍔犲叆瀵硅薄
						elseif v1>2 then                                           
							for i=vp1.began,vp1.ended do
								--printf('add gDestoryPool row=%d,col=%d',i,sprite.col)
								if i ~= sprite.row then
									destoryArgs = {}
									destoryArgs.sprite = gSprites[i][sprite.col]  
									destoryArgs.score = 60*(v1-2)
									destoryArgs.notDisplayscore = false
									destoryArgs.changeToEffect = false
									gDestoryPool[#gDestoryPool+1] = destoryArgs 				--寰�娓呴櫎姹犻噷鍔犲叆瀵硅薄
								end
							end
							destoryArgs = {}
							destoryArgs.sprite = sprite  
							destoryArgs.score = 60*(v1-2)
							destoryArgs.notDisplayscore = false
							local toEffect = nil
							if v1>4 then toEffect = 'bomb' 							   --5娑�
							elseif v1 == 4 then toEffect = 'horizontal' 				   --4娑�
							end
							if sprite.effect and sprite.effect ~= toEffect then  									   --濡傛灉涔嬪墠瀛樺湪鐗规晥锛屽垯澧炲姞涓�鐗规晥锛屽垹闄ゆ椂灏嗗悓鏃惰Е鍙�
								sprite.effect2 = toEffect
							else
								destoryArgs.changeToEffect = toEffect
							end
							gDestoryPool[#gDestoryPool+1] = destoryArgs 				--寰�娓呴櫎姹犻噷鍔犲叆瀵硅薄
						end
					end
					gEventDispatchCentre:dispatchEvent({name = 'cleanupDestoryPool'})
				end
			end
		end
	end
end


function MainScene.onLandTurn()

	local theSprites = {}
	--筛选可左右移动的点
	for r=2,9 do
		for c=1,8 do
			if baseCanTurnMap[r][c][1] == 1 or baseCanTurnMap[r][c][2] == 1 then 	--当前点是否可左右移动
				gSprites[r] = gSprites[r] or {}
				if gSprites[r][c] and gSprites[r][c].sytle ~= 11 then 				--该点存在精灵，且非墙
					local args = {}
					args.sprite = gSprites[r][c]
					if baseCanTurnMap[r][c][1] == 1 then
						args.canLeft = true
					else
						args.canLeft = false
					end
					if baseCanTurnMap[r][c][2] == 1 then
						args.canRight = true
					else
						args.canRight = false
					end
					theSprites[#theSprites+1] = args
				end
			end
		end
	end
	if #theSprites == 0 then return false end
	--[[
	printf('... in onLandTurn : theSprites size = %d ...',#theSprites)
	printf('... the points is:')
	for i=1,#theSprites do
		local tmp = theSprites[i]
		c,r = tmp.sprite.col,tmp.sprite.row
		printf('                    (%d,%d)',c,r)
	end
	--]]
	function createActions(tager,dir)
		local row,col = tager.row,tager.col
		local points = {}
		points[#points+1] = {col=col,row=row}
		local isOver = false
		if dir == 'left' then
			if col-1<1 or row-1<1 then return false end
			for c=col-1,1,-1 do
				if isOver then break end
				for r=row-1,1,-1 do
					gSprites[r] = gSprites[r] or {}
					if baseMap[r][c] == 0 or baseWall[r][c] == 1 or gSprites[r][c] or intentToPoint[r][c]==1 then
						local _row,_col = points[#points].row,points[#points].col
						if _row - r > 1 then
							points[#points+1]={col=c,row=r+1}
						else
							--intentToPoint[r][c]=1 										--标记目标点被站用，下一个不要在判断
							isOver = true							
						end
						break
					elseif r== 1 then
						points[#points+1]={col=c,row=1}
						--intentToPoint[1][c]=0 											--标记目标点被站用，下一个不要在判断
						isOver = true
						break
					end
				end
			end
			if #points == 1 then return false end
			--printf('... in onLandTurn : points size = %d ...',#points)
			local actions = {}
			for i=2,#points do
				actions[#actions+1] = cc.MoveBy:create(0.15,cc.p(-64,-64))
				local dy = points[i-1].row - points[i].row
				if dy > 2 then
					actions[#actions+1] = cc.MoveBy:create(0.08*(dy-1),cc.p(0,-64*(dy-1)))
				end
			end
			intentToPoint[points[#points].row][points[#points].col]=0 			--标记目标点被站用，下一个不要在判断
			return actions,points[#points]  									--返回动画及结束点坐标
		else
			if col+1>8 then return false end
			for c=col+1,8 do
				if isOver then break end
				for r=row-1,1,-1 do
					gSprites[r] = gSprites[r] or {}
					if baseMap[r][c] == 0 or baseWall[r][c] == 1 or gSprites[r][c] or intentToPoint[r][c]==1 then
						local _row,_col = points[#points].row,points[#points].col
						if _row - r > 1 then
							points[#points+1]={col=c,row=r+1}
						else
							isOver = true
						end
						break
					elseif r== 1 then
						points[#points+1]={col=c,row=1}
						isOver = true
						break
					end
				end
			end
			if #points == 1 then return false end
			local actions = {}
			for i=2,#points do
				actions[#actions+1] = cc.MoveBy:create(0.15,cc.p(64,-64))
				local dy = points[i-1].row - points[i].row
				if dy > 2 then
					actions[#actions+1] = cc.MoveBy:create(0.08*(dy-1),cc.p(0,-64*(dy-1)))
				end
			end
			intentToPoint[points[#points].row][points[#points].col]=1 			--标记目标点被站用，下一个不要在判断
			return actions,points[#points]  									--返回动画及结束点坐标
		end
	end

	local isAction = false
	for _,v in ipairs(theSprites) do
		local dir,result,endPoint

		--能左能右，随机取个
		if v.canLeft and v.canRight then
			local n = math.random(1,2)
			if n == 1 then
				result,endPoint =  createActions(v.sprite,'left')
				if not result and v.canRight then
					result,endPoint = createActions(v.sprite,'right')
				end
				if result then
					--printf('... in onLandTurn : result is actions size = %d ...',#result)
					result[#result+1] = cc.CallFunc:create(function()
						gLandNumber = gLandNumber - 1
						v.sprite.gLandNumber =v.sprite.gLandNumber - 1
						gSprites[v.sprite.row][v.sprite.col] = nil
						local x,y = v.sprite:getPosition()
						local _c,_r = BaseSprite.toMatrix(x,y)
						v.sprite.col,v.sprite.row = _c,_r
						gSprites[_r][_c] = v.sprite
						if gStopSoundEffect then audio.playSound('turn1.mp3') end
						intentToPoint[endPoint.row][endPoint.col]=0 			--取消标记
						v.sprite.intentToPoint = nil
					end)
					gLandNumber = gLandNumber + 1
					v.sprite.gLandNumber = v.sprite.gLandNumber + 1
					v.sprite:runAction(cc.Sequence:create(result))
					v.sprite.intentToPoint = endPoint
					isAction = true
				end
			else
				result,endPoint =  createActions(v.sprite,'right')
				if result then
					--printf('... in onLandTurn : result is actions size = %d ...',#result)
					result[#result+1] = cc.CallFunc:create(function()
						gLandNumber = gLandNumber - 1
						v.sprite.gLandNumber = v.sprite.gLandNumber - 1
						gSprites[v.sprite.row][v.sprite.col] = nil
						local x,y = v.sprite:getPosition()
						local _c,_r = BaseSprite.toMatrix(x,y)
						v.sprite.col,v.sprite.row = _c,_r
						gSprites[_r][_c] = v.sprite
						if gStopSoundEffect then audio.playSound('turn1.mp3') end
						intentToPoint[endPoint.row][endPoint.col]=0 			--取消标记
						v.sprite.intentToPoint = nil
					end)

					gLandNumber = gLandNumber + 1
					v.sprite.gLandNumber = v.sprite.gLandNumber + 1
					v.sprite:runAction(cc.Sequence:create(result))
					v.sprite.intentToPoint = endPoint
					isAction = true
				end
			end
		elseif v.canLeft then
			result,endPoint =  createActions(v.sprite,'left')
			if not result and v.canRight then
				result,endPoint = createActions(v.sprite,'right')
			end
			if result then
				--printf('... in onLandTurn : result is actions size = %d ...',#result)
				result[#result+1] = cc.CallFunc:create(function()
					gLandNumber = gLandNumber - 1
					v.sprite.gLandNumber =v.sprite.gLandNumber - 1
					gSprites[v.sprite.row][v.sprite.col] = nil
					local x,y = v.sprite:getPosition()
					local _c,_r = BaseSprite.toMatrix(x,y)
					v.sprite.col,v.sprite.row = _c,_r
					gSprites[_r][_c] = v.sprite
					if gStopSoundEffect then audio.playSound('turn1.mp3') end
					intentToPoint[endPoint.row][endPoint.col]=0 			--取消标记
					v.sprite.intentToPoint = nil
				end)
				gLandNumber = gLandNumber + 1
				v.sprite.gLandNumber = v.sprite.gLandNumber + 1
				v.sprite:runAction(cc.Sequence:create(result))
				v.sprite.intentToPoint = endPoint
				isAction = true
			end
		elseif v.canRight then
			result,endPoint =  createActions(v.sprite,'right')
			if result then
				--printf('... in onLandTurn : result is actions size = %d ...',#result)
				result[#result+1] = cc.CallFunc:create(function()
					gLandNumber = gLandNumber - 1
					v.sprite.gLandNumber = v.sprite.gLandNumber - 1
					gSprites[v.sprite.row][v.sprite.col] = nil
					local x,y = v.sprite:getPosition()
					local _c,_r = BaseSprite.toMatrix(x,y)
					v.sprite.col,v.sprite.row = _c,_r
					gSprites[_r][_c] = v.sprite
					if gStopSoundEffect then audio.playSound('turn1.mp3') end
					intentToPoint[endPoint.row][endPoint.col]=0 			--取消标记
					v.sprite.intentToPoint = nil
				end)

				gLandNumber = gLandNumber + 1
				v.sprite.gLandNumber = v.sprite.gLandNumber + 1
				v.sprite:runAction(cc.Sequence:create(result))
				if gStopSoundEffect then audio.playSound('turn1.mp3') end
				v.sprite.intentToPoint = endPoint
				isAction = true
			end
		end

	end
	return isAction
end

function MainScene:reBuildMatrix()
	gBuildingMatrix = true
	MatrixMap.reRandomGSprites(self) 									--鐢熸垚鏂扮殑鐭╅樀

	--鍏堢Щ鍑哄睆骞�
	for row=1,9 do
		for col=1,8 do
			if baseMap[row][col] == 1 and baseWall[row][col] == 0 then
				gSprites[row] = gSprites[row] or {}
				if gSprites[row][col] then
					if row%2 == 1 then
						gSprites[row][col]:runAction(cc.EaseExponentialIn:create(cc.MoveTo:create(0.4,cc.p(display.width+100,display.cy))))
					else
						gSprites[row][col]:runAction(cc.EaseExponentialIn:create(cc.MoveTo:create(0.4,cc.p(-display.width-100,display.cy))))
					end
				else
					if not gSprites[row][col] then
						local file = SPRITE_SOURCES[math.random(1,5)]
						local tmpSprite = BaseSprite.new({filename=file,row=row,column=col}):addTo(self)
						tmpSprite:setScale(0.5)
						gSprites[row] = gSprites[row] or {}
						gSprites[row][col] = tmpSprite
						tmpSprite:retain()
						if row%2 == 1 then
							gSprites[row][col]:pos(display.width+100,display.cy)
						else
							gSprites[row][col]:pos(-display.width-100,display.cy)
						end
					end
				end
			end
		end
	end


	function checkMatrix()
		if not MatrixMap.checkGSprites(self) then 
			print('random create matrix is bad')	
			MatrixMap.doReviseGSprites(self,false) 						--false,涓嶈鑷姩鏇存柊浣嶇疆
		end
		--鍒ゆ柇鐭╅樀鏄惁鏈夊彲娑堥櫎鐨勶紝濡傛灉娌℃湁鍒欓噸鏂扮敓鎴�
		if MatrixMap.checkGSpritesCanByDestory(self) then
			print('... the matrix is ok ...')
			return true
		else
			print('... the matrix is bad ...')
			MatrixMap.reRandomGSprites(self) 								--閲嶆柊鐢熸垚鐭╅樀鍚庯紝缁х画鍒ゆ柇
			checkMatrix() 	 											    --缁х画鍒ゆ柇			
		end
	end
	checkMatrix()
	--gBuildingMatrix = false

	--绉诲洖灞忓箷
	for row=1,9 do
		for col=1,8 do
			if baseMap[row][col] == 1 and baseWall[row][col] == 0 then
				local x,y = BaseSprite.toPosition(col,row)
				if row%2 == 1 then
					gSprites[row][col]:runAction(
						cc.Sequence:create(
							cc.EaseExponentialIn:create(cc.MoveTo:create(0.4,cc.p(x,y))),
							cc.CallFunc:create(function()
								gBuildingMatrix = false
								gHintTimer = 0
								gLandNumber = 0
							end)
						)
					)
				else
					gSprites[row][col]:runAction(cc.EaseExponentialIn:create(cc.MoveTo:create(0.4,cc.p(x,y))))
				end
			end
		end
	end

end

local isMusicPlaying = true
gStopSoundEffect = true
function MainScene:createButtons()
	local button1 = cc.ui.UIPushButton.new({normal = '#button1.png',pressed = '#button0.png'})
						:onButtonClicked(function(event)
							print('... button1 is clicked ...')
							if isMusicPlaying then
								print('pauseMusic MusicPlaying')
								isMusicPlaying = false
								audio.pauseMusic()
							else
								print('resume MusicPlaying')
								isMusicPlaying = true
								audio.resumeMusic()
							end
						end)
						:setButtonLabel("normal", cc.ui.UILabel.new({UILabelType = 2, text = '静音', size = 48,color=cc.c3b(0,0,0)}))
						:addTo(self)
						:pos(320-64-32,display.height*4/5)
	button1:setScale(0.4)
	local button2 = cc.ui.UIPushButton.new({normal = '#button2.png',pressed = '#button0.png'})
						:onButtonClicked(function(event)
							print('... button2 is clicked ...')
							gStopSoundEffect = not gStopSoundEffect
							printf('change gStopSoundEffect to:%s',tostring(gStopSoundEffect))
							audio.stopAllSounds()
						end)
						:setButtonLabel("normal", cc.ui.UILabel.new({UILabelType = 2, text = '静音效', size = 40,color=cc.c3b(0,0,0)}))
						:addTo(self)
						:pos(320-64-32,display.height*3/5)
	button2:setScale(0.4)
	local button3 = cc.ui.UIPushButton.new({normal = '#button3.png',pressed = '#button0.png'})
						:onButtonClicked(function(event)
							print('... button3 is clicked ...')
							baseWall = clone(baseWallBackup)
							baseCanTurnMap = clone(baseCanTurnMapBackup)
							display.replaceScene(MainScene.new())
						end)
						:setButtonLabel("normal", cc.ui.UILabel.new({UILabelType = 2, text = '重来', size = 48,color=cc.c3b(0,0,0)}))
						:addTo(self)
						:pos(320-64-32,display.height*2/5)
	button3:setScale(0.4)
	local button4 = cc.ui.UIPushButton.new({normal = '#button4.png',pressed = '#button0.png'})
						:onButtonClicked(function(event)
							print('... button4 is clicked ...')
							app:exit()
						end)
						:setButtonLabel("normal", cc.ui.UILabel.new({UILabelType = 2, text = '退出', size = 48,color=cc.c3b(0,0,0)}))
						:addTo(self)
						:pos(320-64-32,display.height*1/5)
	button4:setScale(0.4)


end



return MainScene
